package br.org.universa.sgos.negocio;

import java.util.Collection;

import javax.persistence.EntityManager;

import org.apache.log4j.Logger;

import br.org.universa.sgos.entidade.Entidade;
import br.org.universa.sgos.persistencia.dao.DAOAbstrato;

public abstract class BOAbstrato<E extends Entidade> implements IBOAbstrato<E> {

	private static final Logger logger = Logger.getLogger(BOAbstrato.class);

    private DAOAbstrato<E> daoAbstrato;

    protected DAOAbstrato<E> getDaoAbstrato() {
        if (daoAbstrato == null) {
            daoAbstrato = doGetDao();
        }
        return daoAbstrato;
    }

    protected abstract DAOAbstrato<E> doGetDao();

    protected void iniciarTransacao() {
        getDaoAbstrato().iniciarTransacao();
    }

    public EntityManager criarSession() {
        return getDaoAbstrato().criarSession();
    }

    protected void finalizarSession() {
        getDaoAbstrato().finalizarSession();
    }

    protected void commit() {
        getDaoAbstrato().commit();
    }

    protected void rollback() {
        getDaoAbstrato().rollback();
    }

    public Long inserir(E entidade) {
        try {
            iniciarTransacao();
            getDaoAbstrato().inserir(entidade);
            commit();
            return entidade.getId();
        } catch (Exception e) {
            e.printStackTrace();
            rollback();
        } finally {
            finalizarSession();
        }
        return null;
    }

    public void atualizar(E entidade) {
        try {
            iniciarTransacao();
            getDaoAbstrato().atualizar(entidade);
            commit();
        } catch (Exception e) {
            e.printStackTrace();
            rollback();
        } finally {
            finalizarSession();
        }
    }

    public void excluir(E entidade) {

    	logger.info("solicitada exclusao entidade.");

        try {
            iniciarTransacao();

            logger.info("aberta transacao de exclusao.");

            getDaoAbstrato().excluir(entidade);
            logger.info("feita solicita�ao de exclusao.");
            commit();

            logger.info("entidade excluida.");

        } catch (Exception e) {
            e.printStackTrace();
            rollback();
        } finally {
            finalizarSession();
        }

        logger.info("sessao de exclusao finalizada.");
    }

    public E obterPorId(Long id) {
        return (E) getDaoAbstrato().obterPorId(id);
    }

    public Collection<E> consultarTodos() {
        return (Collection<E>) getDaoAbstrato().consultarTodos();
    }

    protected void setSession(EntityManager session) {
        getDaoAbstrato().setEntityManager(session);
    }
}
